## pak文件内容
## 在编辑过程中，文件内容可以由以下方式之一表示：
## _originalPosition(在源文件的位置), _bytes(字节数组), _path(文件路径)。
class_name PakFileContent
extends RefCounted

#region const
## 无效的源文件位置
const ORIGINAL_POSITION_INVALID: int = 0
## 无效的源文件大小
const ORIGINAL_SIZE_INVALID: int = 0
## 无效的字节数组
const BYTES_INVALID: PackedByteArray = []
## 无效的文件路径
const PATH_INVALID: String = ""
#endregion const

#region enum
## pak文件内容类型：TYPE_EMPTY(空), TYPE_ORIGINAL(源文件), TYPE_BYTES(字节数组), TYPE_PATH(文件路径)
enum PakFileContentType {
	## 空
	TYPE_EMPTY = 0, 
	## 源文件
	TYPE_ORIGINAL, 
	## 字节数组
	TYPE_BYTES, 
	## 文件路径
	TYPE_PATH, 
}
#endregion enum

#region variable
## pak文件内容类型
var _type: PakFileContentType = PakFileContentType.TYPE_EMPTY
## 源文件位置
var _originalPosition: int = ORIGINAL_POSITION_INVALID
## 源文件大小
var _originalSize: int = ORIGINAL_SIZE_INVALID
## 字节数组
var _bytes: PackedByteArray = BYTES_INVALID
## 文件路径
var _path: String = PATH_INVALID
#endregion variable

#region SetContent
## 设置源文件，并将内容类型修改为源文件
## 参数：
## originalPosition-源文件位置
## originalSize-源文件大小
## 返回：设置是否成功
func SetOriginal(originalPosition: int, originalSize: int) -> bool:
	if originalPosition > ORIGINAL_POSITION_INVALID and originalSize > ORIGINAL_SIZE_INVALID:
		_type = PakFileContentType.TYPE_ORIGINAL
		_originalPosition = originalPosition
		_originalSize = originalSize
		_bytes = BYTES_INVALID
		_path = PATH_INVALID
		return true
	else:
		return false
		
## 设置字节数组，并将内容类型修改为字节数组
## 参数：
## bytes-字节数组
## 返回：设置是否成功
func SetBytes(bytes: PackedByteArray) -> bool:
	if bytes and not bytes.is_empty():
		_type = PakFileContentType.TYPE_BYTES
		_originalPosition = ORIGINAL_POSITION_INVALID
		_originalSize = ORIGINAL_SIZE_INVALID
		_bytes = bytes
		_path = PATH_INVALID
		return true
	else:
		return false

## 设置文件路径，并将内容类型修改为文件路径
## 参数：
## path-文件路径
## 返回：设置是否成功
func SetPath(path: String) -> bool:
	if path and not path.is_empty() and FileAccess.file_exists(path):
		_type = PakFileContentType.TYPE_PATH
		_originalPosition = ORIGINAL_POSITION_INVALID
		_originalSize = ORIGINAL_SIZE_INVALID
		_bytes = BYTES_INVALID
		_path = path
		return true
	else:
		return false
#endregion SetContent

#region GetType
## 获取pak文件内容的类型
## 返回：pak文件内容的类型
func GetType() -> PakFileContentType:
	return _type
#endregion GetType

#region GetContent
## 获取pak文件的内容
## 参数：
## original_file-原始文件对象
## 返回：pak文件的内容
func GetContent(original_file: FileAccess = null) -> PackedByteArray:
	if _type == PakFileContentType.TYPE_ORIGINAL:
		return _GetContentFromOriginal(original_file)
	elif _type == PakFileContentType.TYPE_BYTES:
		return _bytes
	elif _type == PakFileContentType.TYPE_PATH:
		return FileAccess.get_file_as_bytes(_path)
	else:
		return []

## 从源文件中获取文件内容
## 参数：
## original_file-源文件对象
## 返回：文件内容
func _GetContentFromOriginal(original_file: FileAccess) -> PackedByteArray:
	if (not original_file or not original_file.is_open() or 
		original_file.get_length() <= _originalPosition):
		return []
	original_file.seek(_originalPosition)
	var buffer: PackedByteArray = original_file.get_buffer(_originalSize)
	PakFile.XOR(buffer)
	return buffer
#endregion GetContent

#region
func _to_string() -> String:
	return "内容类型：{1}{0}源文件位置：{2}{0}源文件大小：{3}{0}字节数组：{4}{0}文件路径：{5}".format(
		[ "\n", _type, _originalPosition, _originalSize, _bytes, _path ] )
#endregion
